package com.xiaoyu.base.utils;

import android.annotation.SuppressLint;
import android.view.View;

import com.jakewharton.rxbinding2.view.RxView;

import java.util.concurrent.TimeUnit;

import io.reactivex.Completable;
import io.reactivex.CompletableTransformer;
import io.reactivex.FlowableTransformer;
import io.reactivex.Maybe;
import io.reactivex.MaybeTransformer;
import io.reactivex.ObservableTransformer;
import io.reactivex.SingleTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.schedulers.Schedulers;

@SuppressLint("CheckResult")
public final class RxUtils {

    public static <T> Maybe<T> ofNullable(T value) {
        return value == null ? Maybe.empty() : Maybe.just(value);
    }

    public static <T> FlowableTransformer<T, T> ioToMainFlowableScheduler() {
        return flowable -> flowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static <T> SingleTransformer<T, T> ioToMainSingleScheduler() {
        return single -> single.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static <T> CompletableTransformer ioToMainCompletableScheduler() {
        return completable -> completable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static <T> MaybeTransformer<T, T> ioToMainMaybeScheduler() {
        return maybe -> maybe.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static <T> ObservableTransformer<T, T> ioToMainObservableScheduler() {
        return observer -> observer.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static void disposable(Disposable... disposables) {
        if (disposables == null) {
            return;
        }
        for (Disposable disposable : disposables) {
            if (disposable != null && !disposable.isDisposed()) {
                disposable.dispose();
            }
        }
    }

    public static void runOnMainThread(final Action run) {
        Completable.fromAction(run).subscribeOn(AndroidSchedulers.mainThread()).subscribe(() -> {
        }, Throwable::printStackTrace);
    }

    public static void runOnIOThread(final Action run) {
        Completable.fromAction(run).subscribeOn(Schedulers.io()).subscribe(() -> {
        }, Throwable::printStackTrace);
    }

    public static void runOnComputationThread(final Action run) {
        Completable.fromAction(run).subscribeOn(Schedulers.computation()).subscribe(() -> {
        }, Throwable::printStackTrace);
    }

    public static void runOnNewThread(final Action run) {
        Completable.fromAction(run).subscribeOn(Schedulers.newThread()).subscribe(() -> {
        }, Throwable::printStackTrace);
    }

    public static void clickViewForThrottleFirst(View view, final Action run) {
        clickViewForThrottleFirst(view, 200, run);
    }

    public static void clickViewForThrottleFirst(View view, long windowDuration, final Action run) {
        RxView.clicks(view)
                .throttleFirst(windowDuration, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(o -> run.run(), Throwable::printStackTrace);
    }
}
